#ifndef __MY_LOG_BUFFER__
#define __MY_LOG_BUFFER__
#include <vector>
#include <cassert>
namespace mylog
{
    class Buffer{
        #define DEFAULT_BUFFER_SIZE (2 * 1024 * 1024)
        #define THRESHOLD_BUFFER_SIZE (8 * 1024 * 1024)
        #define INCREMENT_BUFFER_SIZE (4 * 1024 * 1024)
        public:
            Buffer()
            {
                _buffer.resize(DEFAULT_BUFFER_SIZE);
                reset();
            }
            void push(const char* data, size_t len)
            {
                ensureEnoughSize(len);
                std::copy(data,data+len,&_buffer[_write_index]);
                moveWriter(len);
            }
            const char* begin()
            {
                return &_buffer[_read_index];
            }

            size_t ReadAbleSIze()
            {
                return _write_index - _read_index;
            }
            size_t WriteAbleSIze()
            {
                return _buffer.size() - _write_index;
            }
            void swap(Buffer& buffer)
            {
                _buffer.swap(buffer._buffer);
                std::swap(_read_index,buffer._read_index);
                std::swap(_write_index,buffer._write_index);
                // std::cout <<"obuf "<<_read_index<<" "<<_write_index<<std::endl;
                // std::cout <<"ibuf "<<_read_index<<" "<<_write_index<<std::endl;

            }
            void reset()
            {
                _read_index = _write_index = 0;
            }
            bool empty()
            {
                return _read_index == _write_index;
            }
        public:
            void moveReader(size_t size)
            {
                assert(size <= ReadAbleSIze());
                _read_index +=size;
            }
            void moveWriter(size_t size)
            {
                assert(size <= WriteAbleSIze());
                _write_index +=size;

            }
            void ensureEnoughSize(size_t len)
            {
                size_t wsize = WriteAbleSIze();
                if(wsize >= len)
                {
                    return;
                }
                size_t newsize = 0;
                if(_buffer.size() < THRESHOLD_BUFFER_SIZE)
                {
                    newsize = _buffer.size() * 2;
                }
                else
                {
                    while(newsize + wsize < len)
                    {
                        newsize += INCREMENT_BUFFER_SIZE;
                    }
                    newsize = _buffer.size();
                }
                _buffer.resize(newsize);
            }
        private:
            std::vector<char> _buffer;
            size_t _read_index;
            size_t _write_index;
    };
}



#endif